<?php

namespace unifiedpay\plugins;
use Exception;

require_once dirname(__FILE__)."/vendor/autoload.php";

class Qpay
{
	static public $info = [
		'name' => 'qpay',
		'sort' => 3,
		'link' => 'https://mp.qpay.tenpay.com/',
		'types' => ['qpay'],
	];

	public $channel;
	private $settings;
	private $notify_url;

	public function __construct() {
		global $_G;
		$this->settings = $this->getConfig();
		$this->notify_url = $_G['siteurl'] . 'api/payment/notify/notify_qpay.php';
	}

	private function getConfig() {
		$settings = \C::t('common_setting')->fetch_setting('unifiedpay_qpay', true);
		if($settings['sslcert_path'])
			$settings['sslcert_path'] = DISCUZ_ROOT.$settings['sslcert_path'];
		if($settings['sslkey_path'])
			$settings['sslkey_path'] = DISCUZ_ROOT.$settings['sslkey_path'];
		return $settings;
	}

	public function pay($order) {
		\C::t('common_payment_order')->update($order['id'], array('channel' => 'qpay', 'plugin' => 'qpay'));
		return $this->qpay_qrpay($order);
	}

	public function pay_jsapi($order) {
		global $_G;
		if(strtoupper($_G['charset'] != 'UTF-8')) {
			$order['subject'] = diconv($order['subject'], $_G['charset'], 'UTF-8');
		}
		$params = [
			'out_trade_no' => $order['out_biz_no'],
			'body' => $order['subject'],
			'fee_type' => 'CNY',
			'notify_url' => $this->notify_url,
			'spbill_create_ip' => $_G['clientip'],
			'total_fee' => intval($order['amount']),
		];
		try{
			$client = new \QQPay\PaymentService($this->settings);
			$result = $client->jsapiPay($params);
			return array('code' => 200, 'url' => $result['prepay_id']);
		}catch(Exception $e){
			$errmsg = $e->getMessage();
			if($errmsg && strtoupper($_G['charset'] != 'UTF-8')) {
				$errmsg = diconv($errmsg, 'UTF-8', $_G['charset']);
			}
			return array('code' => 501, 'message' => $errmsg);
		}
	}

	private function qpay_qrpay($order) {
		global $_G;
		if(strtoupper($_G['charset'] != 'UTF-8')) {
			$order['subject'] = diconv($order['subject'], $_G['charset'], 'UTF-8');
		}
		$params = [
			'out_trade_no' => $order['out_biz_no'],
			'body' => $order['subject'],
			'fee_type' => 'CNY',
			'notify_url' => $this->notify_url,
			'spbill_create_ip' => $_G['clientip'],
			'total_fee' => intval($order['amount']),
		];
		try{
			$client = new \QQPay\PaymentService($this->settings);
			$result = $client->nativePay($params);
			return array('code' => 200, 'type' => 'qrcode', 'url' => $result['code_url']);
		}catch(Exception $e){
			$errmsg = $e->getMessage();
			if($errmsg && strtoupper($_G['charset'] != 'UTF-8')) {
				$errmsg = diconv($errmsg, 'UTF-8', $_G['charset']);
			}
			return array('code' => 501, 'message' => $errmsg);
		}
	}

	public function status($out_biz_no) {
		global $_G;
		try{
			$client = new \QQPay\PaymentService($this->settings);
			$result = $client->orderQuery(null, $out_biz_no);
			if($result['trade_state'] == 'SUCCESS'){
				$pay_time = strtotime(preg_replace('/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/', '$1-$2-$3 $4:$5:$6', $result['time_end']));
				return array('code' => 200, 'data' => array('trade_no' => $result['transaction_id'], 'payment_time' => $pay_time));
			}else{
				$order_state = array('REFUND'=>'转入退款', 'NOTPAY'=>'未支付', 'CLOSED'=>'已关闭', 'USERPAYING'=>'用户支付中', 'PAYERROR'=>'支付失败');
				throw new Exception('订单状态：'.($order_state[$result['trade_state']]?$order_state[$result['trade_state']]:$result['trade_state']));
			}
		}catch(Exception $e){
			$errmsg = $e->getMessage();
			if($errmsg && strtoupper($_G['charset'] != 'UTF-8')) {
				$errmsg = diconv($errmsg, 'UTF-8', $_G['charset']);
			}
			return array('code' => 501, 'message' => $errmsg);
		}
	}

	public function refund($refund_no, $trade_no, $total_amount, $refund_amount, $refund_desc) {
		global $_G;
		$params = [
			'transaction_id' => $trade_no,
			'out_refund_no' => $refund_no,
			'refund_fee' => $refund_amount,
		];
		try{
			$client = new \QQPay\PaymentService($this->settings);
			$result = $client->refund($params);
			return array('code' => 200, 'data' => array('refund_time' => time()));
		} catch(Exception $e) {
			$errmsg = $e->getMessage();
			if($errmsg && strtoupper($_G['charset'] != 'UTF-8')) {
				$errmsg = diconv($errmsg, 'UTF-8', $_G['charset']);
			}
			return array('code' => 501, 'message' => $errmsg);
		}
	}

	public function refund_status($refund_no, $trade_no) {
		global $_G;
		$params = [
			'out_refund_no' => $refund_no
		];
		try{
			$client = new \QQPay\PaymentService($this->settings);
			$result = $client->refundQuery($params);
			return array('code' => 200, 'data' => array('refund_time' => time()));
		} catch(Exception $e) {
			$errmsg = $e->getMessage();
			if($errmsg && strtoupper($_G['charset'] != 'UTF-8')) {
				$errmsg = diconv($errmsg, 'UTF-8', $_G['charset']);
			}
			return array('code' => 501, 'message' => $errmsg);
		}
	}

	public function transfer($transfer_no, $amount, $realname, $account, $title = '', $desc = '') {
		global $_G;
		if(strtoupper($_G['charset'] != 'UTF-8')) {
			$title = diconv($title, $_G['charset'], 'UTF-8');
			$desc = diconv($desc, $_G['charset'], 'UTF-8');
		}
		try{
			$client = new \QQPay\TransferService($this->settings);
			$result = $client->transfer($transfer_no, $account, $realname, $amount, $desc);
			return array('code' => 200, 'data' => array('refund_time' => time()));
		} catch(Exception $e) {
			$errmsg = $e->getMessage();
			if($errmsg && strtoupper($_G['charset'] != 'UTF-8')) {
				$errmsg = diconv($errmsg, 'UTF-8', $_G['charset']);
			}
			return array('code' => 501, 'message' => $errmsg);
		}
	}

	public function transfer_status($transfer_no) {
		global $_G;
		try{
			$client = new \QQPay\TransferService($this->settings);
			$result = $client->transferQuery($transfer_no);
			if($result['state'] == 'SUCCESS'){
				return array('code' => 200, 'data' => array('refund_time' => strtotime($result['transfer_time'])));
			}else{
				return array('code' => 500, 'message' => $result['state']);
			}
		} catch(Exception $e) {
			$errmsg = $e->getMessage();
			if($errmsg && strtoupper($_G['charset'] != 'UTF-8')) {
				$errmsg = diconv($errmsg, 'UTF-8', $_G['charset']);
			}
			return array('code' => 501, 'message' => $errmsg);
		}
	}

	public function notify() {
		$isSuccess = true;
		try{
			$client = new \QQPay\PaymentService($this->settings);
			$data = $client->notify();
			$out_biz_no = $data['out_trade_no'];
			unifiedpay_process_notify($out_biz_no, $data['transaction_id'], $data['openid']);
		}catch(Exception $e){
			$isSuccess = false;
			$errmsg = $e->getMessage();
		}
		$client->replyNotify($isSuccess, $errmsg);
	}
}